import wx
import ConfigfileReader

##  Contains a visual representation of the location of all sensors on the body. The location of all the sensors is validated in this panel.
class SensorPanel(wx.Panel):

    ##  The constructor of SensorPanel. GUI elements of the panel are setup here.
    #   @param[in]  parent  The wx window parent (notebook) of this panel.
    #   @param[in]  state   SensorState instance attached to this panel.
    def __init__(self, parent, state):
        wx.Panel.__init__(self, parent)
        ##  SensorState instance attached to this panel.
        self.state = state
        ##  The wx window parent (notebook) of this panel.
        self.parent = parent
        ##  The name of this notebook panel.
        self.name = "Sensors"         

        self.sensorHelp_staticbox = wx.StaticBox(self, -1, "Help")
        self.sensorsLocations_staticbox = wx.StaticBox(self, -1, "Locations")

        # We want to show a table of GSI - position string.
        # Here the sensors read from the file are placed in a list and added to the interface.
        # These sensors are the "Active sensors" in the confi.ini file.
        gp_dict = state.get_sensor_positions()
        gsi_list = gp_dict.keys()
        gsi_list.sort()
        ##  Sensor number on the GUI.
        self.gsi_labels = []
        ##  Sensor description of the sensors in gsi_labels.
        self.pos_labels = []
        for gsi in gsi_list:
            sensornumber = gsi.split('_')
            self.gsi_labels.append(wx.StaticText(self, -1, "Sensor "+sensornumber[1]))
            self.pos_labels.append(wx.StaticText(self, -1, gp_dict[gsi]))

        helpText = "Place the sensors on the patients body according to the locations displayed in the diagram. "
        self.label_help = wx.StaticText(self, -1, helpText)

        self.body_picture = wx.StaticBitmap(self, -1, wx.Bitmap("Images/Body.png", wx.BITMAP_TYPE_ANY))
        self.panel_1 = wx.Panel(self, -1)
        self.panel_2 = wx.Panel(self, -1)
        self.panel_3 = wx.Panel(self, -1)
        self.panel_4 = wx.Panel(self, -1)
        self.panel_5 = wx.Panel(self, -1)
        self.panel_6 = wx.Panel(self, -1)
        self.static_line_5 = wx.StaticLine(self, -1)
        self.static_line_6 = wx.StaticLine(self, -1)
        self.static_line_7 = wx.StaticLine(self, -1)
        ##  Goes to the previous panel.
        self.sensorsBackButton = wx.Button(self, -1, "< Back")
        ##  Goes to the next panel.
        self.sensorsNextButton = wx.Button(self, -1, "Next >")

        # The sensor positions on the body.
        coord_labels = []
        coord_dict = self.state.main.sensorPictPos
        for position, coord in coord_dict.items():
            coord_labels.append(wx.StaticText(self, -1, position, coord, (-1,-1)))

        self.__SetProperties()
        self.__DoLayout()

        #Sets an event handles for the next button
        self.sensorsNextButton.Bind(wx.EVT_BUTTON, self.OnNext)

    ##  Sets several properties of the panel.
    def __SetProperties(self):
        self.sensorsBackButton.Disable()
        self.label_help.SetMinSize((150, 254))

    ##  Sets layout of the panel.
    def __DoLayout(self):
        sizer_1 = wx.BoxSizer(wx.VERTICAL)
        grid_sizer_1 = wx.FlexGridSizer(4, 3, 0, 0)
        grid_sizer_3 = wx.FlexGridSizer(1, 2, 0, 10)
        sensorHelp = wx.StaticBoxSizer(self.sensorHelp_staticbox, wx.HORIZONTAL)
        sensorsLocations = wx.StaticBoxSizer(self.sensorsLocations_staticbox, wx.HORIZONTAL)
        sensorsGrid = wx.FlexGridSizer(len(self.gsi_labels), 2, 5, 10)

        for gsi_label, pos_label in zip(self.gsi_labels,\
                                        self.pos_labels):
            sensorsGrid.Add(gsi_label, 0, 0, 0)
            sensorsGrid.Add(pos_label, 0, 0, 0)

        sensorsLocations.Add(sensorsGrid, 1, wx.ALL|wx.EXPAND, 10)
        sensorsLocations.Add(self.body_picture, 0, wx.ALL, 10)
        grid_sizer_1.Add(sensorsLocations, 1, wx.ALL, 10)
        grid_sizer_1.Add(self.panel_1, 1, wx.EXPAND, 0)
        sensorHelp.Add(self.label_help, 0, wx.ALL, 10)
        grid_sizer_1.Add(sensorHelp, 1, wx.ALL|wx.ALIGN_RIGHT, 10)
        grid_sizer_1.Add(self.panel_4, 1, wx.EXPAND, 0)
        grid_sizer_1.Add(self.panel_6, 1, wx.EXPAND, 0)
        grid_sizer_1.Add(self.panel_2, 1, wx.EXPAND, 0)
        grid_sizer_1.Add(self.static_line_5, 0, wx.EXPAND, 0)
        grid_sizer_1.Add(self.static_line_6, 0, wx.EXPAND, 0)
        grid_sizer_1.Add(self.static_line_7, 0, wx.EXPAND, 0)
        grid_sizer_1.Add(self.panel_3, 1, wx.EXPAND, 0)
        grid_sizer_1.Add(self.panel_5, 1, wx.EXPAND, 0)
        grid_sizer_3.Add(self.sensorsBackButton, 0, wx.ALIGN_RIGHT, 0)
        grid_sizer_3.Add(self.sensorsNextButton, 0, wx.RIGHT|wx.ALIGN_RIGHT, 10)
        grid_sizer_1.Add(grid_sizer_3, 1, wx.TOP|wx.BOTTOM|wx.ALIGN_RIGHT|wx.ALIGN_BOTTOM, 5)
        grid_sizer_1.AddGrowableRow(1)
        grid_sizer_1.AddGrowableCol(2)
        sizer_1.Add(grid_sizer_1, 1, wx.EXPAND, 0)
        self.SetSizer(sizer_1)
        sizer_1.Fit(self)
        self.Layout()

    ##  Handles events when the next button is pressed.
    #   @param[in]          new The tab index to go to.
    #   @return[boolean]    False when navigation to following panel is somehow cancelled, else True.
    def OnNext(self, event, new=1):
        NAVIGATED_TO_NEXT = False

        # Check using the rulebase if the sensors are placed correctly relative to eachother.
        # If they are not, a checkbox asking whether the user wants to continue or not is displayed.
        if self.state.CheckSensors() == False:
            msg = "The actual sensor positions do not correspond with the given positions.\nAre you sure you want to continue?"
            dlg = wx.MessageDialog(self, msg, 'Warning', wx.YES_NO | wx.NO_DEFAULT | wx.ICON_EXCLAMATION)
            # User wants to continue even though the sensors are placed incorrectly.
            if(dlg.ShowModal() == wx.ID_YES):
                self.parent.ChangeSelection(new)
                NAVIGATED_TO_NEXT = True
            # User doesn't want to continue to next panel.
            else:
                self.parent.ChangeSelection(0)

            dlg.Destroy()
        # Sensors have been place correctly, and next menu panel is selected.
        else:
            NAVIGATED_TO_NEXT = True
            self.parent.ChangeSelection(new)

        return NAVIGATED_TO_NEXT
